<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">



  
  
    
    
  <script src="/lib/pace/pace.min.js?v=1.0.2"></script>
  <link href="/lib/pace/pace-theme-minimal.min.css?v=1.0.2" rel="stylesheet">







<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="freeswitch," />





  <link rel="alternate" href="/atom.xml" title="搁浅丶岁月的变迁" type="application/atom+xml" />






<meta name="description" content="SIP信令, 帮我们建立会话, 但我们建立通话的目的是”通话” 要通过采样, 量化, 编码将我们声音的模块量变成数字信号, 以便在数字线路上传输, 我们把这些数字信号成为媒体(Media) 1.媒体与媒体处理常见媒体有音频, 视频, 图像, 文本等,  1） 音频编码      从模拟信号变成数字信号的过程成为模数转换(AD)          经过采样,量化,编码三个过程          编码">
<meta name="keywords" content="freeswitch">
<meta property="og:type" content="article">
<meta property="og:title" content="8.媒体">
<meta property="og:url" content="http://yoursite.com/2017/12/23/2017-12-23-8.媒体/index.html">
<meta property="og:site_name" content="搁浅丶岁月的变迁">
<meta property="og:description" content="SIP信令, 帮我们建立会话, 但我们建立通话的目的是”通话” 要通过采样, 量化, 编码将我们声音的模块量变成数字信号, 以便在数字线路上传输, 我们把这些数字信号成为媒体(Media) 1.媒体与媒体处理常见媒体有音频, 视频, 图像, 文本等,  1） 音频编码      从模拟信号变成数字信号的过程成为模数转换(AD)          经过采样,量化,编码三个过程          编码">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2018-05-28T08:47:52.164Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="8.媒体">
<meta name="twitter:description" content="SIP信令, 帮我们建立会话, 但我们建立通话的目的是”通话” 要通过采样, 量化, 编码将我们声音的模块量变成数字信号, 以便在数字线路上传输, 我们把这些数字信号成为媒体(Media) 1.媒体与媒体处理常见媒体有音频, 视频, 图像, 文本等,  1） 音频编码      从模拟信号变成数字信号的过程成为模数转换(AD)          经过采样,量化,编码三个过程          编码">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/2017/12/23/2017-12-23-8.媒体/"/>





  <title>8.媒体 | 搁浅丶岁月的变迁</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>
    <a href="https://github.com/liaoren512"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_left_red_aa0000.png" alt="Fork me on GitHub"></a>
    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">搁浅丶岁月的变迁</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">没有虽败犹荣，只有成王败寇。</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/12/23/2017-12-23-8.媒体/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="廖壬">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/ichgo.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="搁浅丶岁月的变迁">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">8.媒体</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2017-12-23T00:00:00+08:00">
                2017-12-23
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          
            <span class="post-meta-divider">|</span>
            <span class="page-pv"><i class="fa fa-file-o"></i>
            <span class="busuanzi-value" id="busuanzi_value_page_pv" ></span>
            </span>
          

          
            <div class="post-wordcount">
              
                
                <span class="post-meta-item-icon">
                  <i class="fa fa-file-word-o"></i>
                </span>
                
                  <span class="post-meta-item-text">字数统计&#58;</span>
                
                <span title="字数统计">
                  
                </span>
              

              
                <span class="post-meta-divider">|</span>
              

              
                <span class="post-meta-item-icon">
                  <i class="fa fa-clock-o"></i>
                </span>
                
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                
                <span title="阅读时长">
                  
                </span>
              
            </div>
          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>SIP信令, 帮我们建立会话, 但我们建立通话的目的是”通话”</p>
<p>要通过采样, 量化, 编码将我们声音的模块量变成数字信号,</p>
<p>以便在数字线路上传输, 我们把这些数字信号成为媒体(Media)</p>
<h2 id="1-媒体与媒体处理"><a href="#1-媒体与媒体处理" class="headerlink" title="1.媒体与媒体处理"></a>1.媒体与媒体处理</h2><pre><code>常见媒体有音频, 视频, 图像, 文本等,

1） 音频编码

    从模拟信号变成数字信号的过程成为模数转换(AD)

        经过采样,量化,编码三个过程

        编码:

            按照一定的规则将采样的信号用一组二进制或其他进制的数表示

        经过编码的数据在网络上传输,到达对端后

    通过解码,变成原始信号

        再经过数模转换(DA),转换为人们能感知的信号

    编码, 解码都是成对出现,所以习惯是称为编解码Codec,为了方便,简称编码



    PCM编码

        PCM的两种压缩方式A律和u律,分别为PCMA和PCMU

        经过PCM编码仍然占用比较高的带宽,又出现了一些更高级的压缩算法,目的都是降低带宽,提高传输效率

        CPM采样频率为8000Hz,随着人们对声音质量要求的提高,各种高清(HD)编码纷纷涌现,如G.722等

    打包

        在网络上传输语音,要将编码后的语音数据打包,通常打包时间间隔为20ms,

        如果采样频率是8000Hz,1s传输1000ms/20ms= 50个包,

        每个包携带8000/50=160个采样数据,

        在PCMU和PCMA中一个采样数据占1字节,因此一个20ms的PCM包数据净荷是160字节

    Freeswitch支持的语音编码

        G.711: PCM

        G.722: 高清语音

        G.726

        G.723.1

        G.729: 低带宽8kbit/s

        GSM: 13.3kbit/s

         iLBC: 抗丢包,绝大多数情况下都是最佳选择

        iSAC

        CODEC2: 2550bit/s, 最省带宽

        Speex

        SILK: skype,抗丢包

        CELT: 低延迟高清编码, 48kbit/s,达到CD音质

        OPUS: 综合CELT和SILK之长

    编码格式

        名词@xx@yyi,h代表Hz采样频率;i代表ptime,打包间隔;xx,yy代表实际数值

        如speex@16000h@20i

            16000Hz,20ms的Speex编码

    查看Freeswitch支持的编码类型

        show codec

    音频编码最基本的两个技术参数就是采样频率和打包周期

        采样频率越高,声音越清晰,通常8000Hz就够了

        打包周期越短,延迟越小,传输开销就越大,需要更大带宽,最常见的是20ms

2） 媒体工作机理和相关配置

    工作原理

        以PCM音频数据为例, 打包周期是20ms,音频包得到160字节的数据,

        加上12字节的RTP包头,就成了一个RTP包,RTP包头包含音频编码类型,时间戳等,便于对方解码回放及同步等

        RTP使用与SIP不同的UDP端口传送,在实际传输前需要通过SIP信令与对方协商往哪个端口传送

        A: 你好,我的RTP端口是10000

        B: 收到,我的RTP端口是20000

        A音频打包,通过RTP发送到B20000端口

        B音频打包,通过RTP发送到A10000端口

    相关配置

        SIP Profile支持的媒体列表是在vars.xml配置

            &lt;X-PRE-PROCESS cmd=&quot;set&quot; data=&quot;global_codec_prefs=G722,PCMU,PCMA,GSM&quot;/&gt;

            &lt;X-PRE-PROCESS cmd=&quot;set&quot; data=&quot;outbound_codec_prefs=PCMU,PCMA,GSM&quot;/&gt;

        如果学习过程中需要频繁实验,不妨直接修改Profile配置文件

            &lt;param name=&quot;inbound-codc-prefs&quot; value=&quot;$${global_codec_prefs}&quot;/&gt;

            改为

            &lt;param name=&quot;inbound-codc-prefs&quot; value=&quot;PCMU,PCMA,G729,iLBC,H264,VP8&quot;/&gt;

            然后在控制台执行命令

                sofia profile internal rescan
</code></pre><h2 id="2-媒体协商"><a href="#2-媒体协商" class="headerlink" title="2.媒体协商"></a>2.媒体协商</h2><pre><code>不同的SIP终端进行通信时需要先与支持的编码进行&quot;协商&quot;,以便双方能互相理解,对方发来的数据

1） 协商过程

    SIP客户端呼入时使用iLBC编码,打包周期是60ms,而服务器端提供G722,PCMU等,但都是20ms

    Freeswitch与客户端提供的编码逐一比较,发现没有交集,协商失败,返回488,INCOMPATIBLE_DESTINATION(目的地不兼容)

    Offer/Answer机制

        请求发起方提供自己支持的媒体编码列表,被请求方比较自己支持的媒体列表最终选择一种应答

    Set Codec sofia/internal/1006@192.168.7.6 PCMA/8000 20ms 160 samples 64000

        本次协商成功,把Channel编码设为PCMA编码

2） SDP及其在编码协商中的作用

    SDP(会话描述协议),说明Freeswitch使用PCMA编码,RTP端口号是28512

    协商完毕

        双方都知道对方的IP地址和端口号,就可以互发音频RTP包了

3） 协商时机与策略

    协商时机

        早协商

            当呼叫到达一个SIP Profile时,某端口收到INVITE请求而未到达路由阶段,就先行协商

        晚协商

            等到路由阶段,到达拨号计划时再行协商,默认使用晚协商

        设置为早协商,修改SIP Profile

            &lt;param name=&quot;inbound-late-negotiation&quot; value=&quot;false&quot;/&gt;

            如果启动inbound-zrtp-passthru,则隐含设置inbound-late-negotiation为true

    协商策略

        generous(普通),默认策略

            客户端提供PCMA,G729,而Freeswitch支持列表优先顺序为G729,PCMU,PCMA

            当Freeswitch收到请求时优先考虑客户端感受,优先使用PCMA

        greedy(贪婪)

            Freeswitch优先考虑自己的编码,选择G729

        scrooge(吝啬)

            除了具有greedy特征外,还强制使用自己的采样率
</code></pre><h2 id="3-其他媒体相关的问题"><a href="#3-其他媒体相关的问题" class="headerlink" title="3.其他媒体相关的问题"></a>3.其他媒体相关的问题</h2><pre><code>1） RTP和RTCP

    在完成SIP及SDP协商后,真正的语音数据在RTP协议中传送,

        即双方在前面的SDP协商中已经获得对方的IP,端口号,以及支持的媒体类型.

    RTP,实时传输协议

        说明了在互联网上传递音频和视频的标准数据包格式,一开始被设计为一个多播协议,后来被用于单播应用

        建立在UDP协议上,常用于流媒体,视频会议和一键通

    RTCP,实时传输控制协议

        RTP使用偶数UDP端口

        RTCP使用下一个相邻的技术端口,RTCP本身不传输数据,但会和RTP协作将多媒体数据打包并发送出去

        RTCP主要功能是为RTP提供的服务的质量提供反馈信息

            收集统计信息,如传输字节数,丢失分组数,单向延迟等

            网络应用利用RTCP统计信息控制传输的品质,当网络阻塞时,限制流量或改用压缩率高的编码

2） 转码

    如果两条腿分别使用不同的编码,则需要经过一个转码过程,分别转成对方需要的编码

    呼叫双方采用同样的编码,但如果有IVR或录音,放音等中间环节时,也需要转码

    Freeswitch默认的配置不支持自动转码

        A呼叫B

        A只有PCMA, B只支持PCMU

        协商失败

        要使协商成功,只需在internal Profile将下面一行注释

            &lt;param name=&quot;inbound-zrtp-passthru&quot; value=&quot;true&quot;/&gt;

        查看重启前后该配置的区别

            sofia status profile internal

        由于A提供PCMA,Freeswitch向B发送SDP的时候,把PCMA放在最前面,

        B收到INVITE后,它仅支持PCMU,它通过200 告诉Freeswitch

        接通后, A向Freeswitch发送PCMA编码的RTP媒体流,Freeswitch自动转换为PCMU,并发给B



3） 透传, 媒体绕过与媒体代理

    Freeswitch不支持G729, 只要通话双方都支持G729,仍可以建立通话

    第一种方式是透传

        在不经过转码的情况下,将从乙方收到的媒体流原样转给另一方

    媒体绕过

        真正的媒体流使用点到点传输, 不经过Freeswitch

        Freeswitch正常建立通话,RTP通过点对点直接传输

4） Media Bug

    为了解决监听和录音问题,Freeswitch在媒体流路径上放了一个Media Bug

    相当于水管上的三通

        媒体流不仅在A于B交换,还通过三通连接到C

    录音也是通过这种机制实现

        C相当于录音机

5） 视频

    Freeswitch也支持视频呼叫和会议, 所有的视频流都是透传, Freeswitch不支持视频转码

    必须保证两端都使用相同的视频编码才可以互看

6） 排错

    媒体协商问题

        打电话在Log查找与&quot;Audio Codec Compare&quot;相关行

    也可以使用外部的抓包工具(tcpdump或Wireshark)来抓包分析

    Freeswitch也提供了一个实用工具,uuid_debug_media,可以比较方便的查看是否有媒体流的收发

        uuid_debug_media 68c65988-ddfb-11e6-8d22-0fcaa3ca5f35 read on/off
</code></pre><h2 id="4-小结"><a href="#4-小结" class="headerlink" title="4.小结"></a>4.小结</h2><pre><code>音视频编码, SDP及RTP

Freeswitch对媒体处理的方法, 协商机制

使用late-negotiatioin, disable-transcoding尽量避免转码,节省系统资源

设置BypassMedia, 让媒体不经过Freeswitch直接在两个SIP客户间点对点传输
</code></pre>
      
    </div>
    
    
    

    <div>
      
        <div>
    
        <div style="text-align:center;color: #ccc;font-size:14px;">-------------本文结束<i class="fa fa-paw"></i>感谢您的阅读-------------</div>
    
</div>

      
    </div>

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <!--<a href="/tags/freeswitch/" rel="tag"># freeswitch</a>-->
            <a href="/tags/freeswitch/" rel="tag"><i class="fa fa-tag"></i> freeswitch</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/12/23/2017-12-23-1.PSTN与VoIP基础/" rel="next" title="1.PSTN与VoIP基础">
                <i class="fa fa-chevron-left"></i> 1.PSTN与VoIP基础
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/12/25/2017-12-25-Centos 7 调整root分区/" rel="prev" title="Centos 7 调整root分区">
                Centos 7 调整root分区 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
        <!-- JiaThis Button BEGIN -->
<div class="jiathis_style">
<span class="jiathis_txt">分享到：</span>
<a class="jiathis_button_fav">收藏夹</a>
<a class="jiathis_button_copy">复制网址</a>
<a class="jiathis_button_email">邮件</a>
<a class="jiathis_button_weixin">微信</a>
<a class="jiathis_button_qzone">QQ空间</a>
<a class="jiathis_button_tqq">腾讯微博</a>
<a class="jiathis_button_douban">豆瓣</a>
<a class="jiathis_button_share">一键分享</a>

<a href="http://www.jiathis.com/share?uid=2140465" class="jiathis jiathis_txt jiathis_separator jtico jtico_jiathis" target="_blank">更多</a>
<a class="jiathis_counter_style"></a>
</div>
<script type="text/javascript" >
var jiathis_config={
  data_track_clickback:true,
  summary:"",
  shortUrl:false,
  hideMore:false
}
</script>
<script type="text/javascript" src="http://v3.jiathis.com/code/jia.js?uid=" charset="utf-8"></script>
<!-- JiaThis Button END -->
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="/images/ichgo.jpg"
                alt="廖壬" />
            
              <p class="site-author-name" itemprop="name">廖壬</p>
              <p class="site-description motion-element" itemprop="description">Learn to choose, to forsake, to endure loneliness, to resist temptation.</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">391</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">11</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">56</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          
            <div class="feed-link motion-element">
              <a href="/atom.xml" rel="alternate">
                <i class="fa fa-rss"></i>
                RSS
              </a>
            </div>
          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/liaoren512" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-github"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="mailto:liaoren512@gmail.com" target="_blank" title="E-Mail">
                      
                        <i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://weibo.com/5281757990/profile?rightmod=1&wvr=6&mod=personinfo" target="_blank" title="Weibo">
                      
                        <i class="fa fa-fw fa-globe"></i>Weibo</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://www.zhihu.com" target="_blank" title="Zhihu">
                      
                        <i class="fa fa-fw fa-globe"></i>Zhihu</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-媒体与媒体处理"><span class="nav-number">1.</span> <span class="nav-text">1.媒体与媒体处理</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-媒体协商"><span class="nav-number">2.</span> <span class="nav-text">2.媒体协商</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-其他媒体相关的问题"><span class="nav-number">3.</span> <span class="nav-text">3.其他媒体相关的问题</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-小结"><span class="nav-number">4.</span> <span class="nav-text">4.小结</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        
<!--<script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>-->

<div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">廖壬</span>

  
</div>

<!-- 在网站底部加上访问量-->
<!--<div class="powered-by">
<i class="fa fa-user-md"></i><span id="busuanzi_container_site_uv">
  本站访客数:<span id="busuanzi_value_site_pv"></span>
</span>
</div>-->
<!--pv的方式，单个用户连续点击n篇文章，记录n次访问量-->
<!--

  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Gemini</a> v5.1.4</div>



-->
<div class="theme-info">
  <div class="powered-by"></div>
  <span class="post-count">博客全站共字</span>
</div>
        
<div class="busuanzi-count">
  <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>

  
    <span class="site-uv">
      <i class="fa fa-user"></i>
      <span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
      
    </span>
  

  
    <span class="site-pv">
      <i class="fa fa-eye"></i>
      <span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
      
    </span>
  
</div>








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  


  



  
  









  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  

  
  
    <script type="text/javascript" src="/lib/canvas-nest/canvas-nest.min.js"></script>
  

  
  
    <script type="text/javascript" src="/lib/three/three.min.js"></script>
  

  
  
    <script type="text/javascript" src="/lib/three/three-waves.min.js"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  

  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'auto') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>





  

  

  

  
  

  

  

  

</body>
</html>
<!-- 页面点击小红心 -->
<script type="text/javascript" src="/js/src/love.js"></script>